package cn.leaf.calculator.bean;


import cn.leaf.calculator.resolver.FormulaResolver;
import cn.leaf.calculator.resolver.SpringELFormulaResolver;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * formula
 *
 * @author 李克国
 * @version 1.0.0

 */
@EqualsAndHashCode(callSuper = true)
@Data
public class FormulationCalUnitEntity<T> extends CalUnitEntity<T> {


    private FormulaResolver<T> formulaResolver;

    private String sourceFormula;

    private String sourceFormulaName;

    private List<ParamEntity<T>> paramEntityList;

    private Map<Serializable, ParamEntity<T>> paramEntityMap;

    public FormulationCalUnitEntity() {
    }

    public FormulationCalUnitEntity(Serializable id, T body, String sourceFormula) {
        super();
        super.setId(id);
        super.setBodyEntity(body);
        this.sourceFormula = sourceFormula;
        initialize();
    }

    public void initialize() {
        Assert.notNull(getBodyEntity(), "CalUnitEntityInitializeException : 计算单元初始化失败，bodyEntity 为空");
        Assert.notNull(getId(), "CalUnitEntityInitializeException : 计算单元初始化失败，id 为空");
        Assert.notNull(sourceFormula, "CalUnitEntityInitializeException : 计算单元初始化失败，sourceFormula 为空");
        if (formulaResolver == null) {
            formulaResolver = new SpringELFormulaResolver<>(sourceFormula);
        }
        paramEntityList = formulaResolver.resolve();
        paramEntityMap = new HashMap<>();
        paramEntityList.forEach(i -> paramEntityMap.put(i.getId(), i));
        updateState(CAL_INIT);
    }

    /**
     * 设置参数
     *
     * @param body 参数体
     */
    public void setParameters(@NonNull ParamEntity<T> body) {
        Assert.notNull(body.getId(), "CalException：参数设置：id 为空");
        paramEntityList.removeIf(p -> p.getId().equals(body.getId()));
        paramEntityList.add(body);
        paramEntityMap.put(body.getId(), body);
    }

    public boolean hasParameters(Serializable id) {
        return paramEntityMap.containsKey(id);
    }

    public void setConverter() {

    }
}
